package main

import "fmt"

func main() {
	switchDemo1()
	switchDemo2()
	switchStruct()
	swicthString()

	x := "hello"
	fmt.Println(getVariableType(x)) //the type of v is string, v = hello
}

func switchDemo1() {
	score := 70
	switch score {
	case 10:
		fmt.Println("未及格10")
	case 20:
		fmt.Println("未及格20")
		break
		fmt.Println("Unreachable code") //当前分支的 break后面的语句 不会再执行
	case 60, 70:
		fmt.Println("及格了60/70")
		fallthrough
	case 80, 90:
		fmt.Println("比较优秀80/90")
	default:
		fmt.Println("分数有问题")
	}
	/*
		输出:
		及格了60/70
		比较优秀80/90
	*/
}

func switchDemo2() {
	score := 75
	switch {
	case score >= 0 && score < 60:
		fmt.Println("未及格")
	case score >= 60 && score < 80:
		fmt.Println("及格了")
	case score >= 80 && score < 95:
		fmt.Println("比较优秀")
	case score >= 95 && score <= 100:
		fmt.Println("三好学生")
	default:
		fmt.Println("分数有问题")
	}
	//输出:及格了
}

/*
switch 语句中的表达式类型可以是:整型、布尔类型、字符串类型、复数类型、数组类型、结构体类型;
使用自定义结构体类型作为 switch 表达式类型的例子：
*/
func switchStruct() {
	type person struct {
		name string
		age  int
	}
	p := person{
		"tom", 13,
	}

	switch p {
	case person{"tony", 33}:
		println("match tony")
	case person{"tom", 13}:
		println("match tom")
	case person{"lucy", 23}:
		println("match lucy")
	default:
		println("no match")
	}

	//输出: match tom
	//不过实际开发过程中，以结构体类型为 switch 表达式类型的情况并不常见
}

func swicthString() {
	switch language := "golang"; language {
	case "php":
		fmt.Println("PHP语言。。")
	case "golang":
		fmt.Println("Go语言")
	case "java":
		fmt.Println("Java语言")
	}
	//输出: Go语言
}

func getVariableType(x interface{}) string {
	switch v := x.(type) { //此处的 v 存储的是变量 x 的动态类型对应的值信息
	case nil:
		return "v is nil"
	case int:
		return fmt.Sprintf("the type of v is int, v = %v", v)
	case string:
		return fmt.Sprintf("the type of v is string, v = %v", v)
	case bool:
		return fmt.Sprintf("the type of v is bool, v = %v", v)
	default:
		return fmt.Sprintf("don't support the type")
	}
}
